/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.kramerius.commons;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 *
 * @author Martin Rehanek (rehan@mzk.cz)
 */
public class PropertyLoader {

    private Properties properties;

    public PropertyLoader(Properties properties) {
        this.properties = properties;
    }

    public PropertyLoader(String propertiesFileName) throws IOException {
        this(new File(propertiesFileName));
    }

    public PropertyLoader(File propertiesFile) throws IOException {
        this(new FileInputStream(propertiesFile));
    }

    public PropertyLoader(InputStream inputStream) throws IOException {
        if (inputStream == null) {
            throw new IllegalStateException("input stream is null");
        }
        properties = new Properties();
        properties.load(inputStream);
    }

    public String loadString(String key) {
        String result = properties.getProperty(key);
        if (result == null || result.isEmpty()) {
            throw new IllegalArgumentException("Cannot load property '" + key + "'");
        }
        return result;
    }

    /**
     *
     * @param key
     * @param mustExist whether file should be checked for existence. If this
     * the parameter is set to true and file doesn't exist the
     * IllegalStateException is thrown.
     * @param mustBeReadable whether it should be checked that user can read the
     * file. If this the parameter is set to true and file cannot be read the
     * IllegalStateException is thrown.
     * @param mustBeWritable wheteher it should be checked that user can write
     * into the file. If this the parameter is set to true and file cannot be
     * written to the IllegalStateException is thrown.
     * @return
     */
    public File loadFile(String key, boolean mustExist, boolean mustBeReadable, boolean mustBeWritable) {
        String fileName = loadString(key);
        File file = new File(fileName);
        if (mustExist && !file.exists()) {
            throw new IllegalStateException("File " + file.getAbsolutePath() + " doesn't exist");
        }
        if (mustBeReadable && !file.canRead()) {
            throw new IllegalStateException("Cannot read file " + file.getAbsolutePath());
        }
        if (mustBeWritable && !file.canWrite()) {
            throw new IllegalStateException("Cannot write to file " + file.getAbsolutePath());
        }
        return file;
    }

    /**
     *
     * @param key
     * @param mustExist whether file should be checked for existence. If this
     * the parameter is set to true and file doesn't exist the
     * IllegalStateException is thrown.
     * @param mustBeReadable whether it should be checked that user can read the
     * file. If this the parameter is set to true and file cannot be read the
     * IllegalStateException is thrown.
     * @param mustBeWritable wheteher it should be checked that user can write
     * into the file. If this the parameter is set to true and file cannot be
     * written to the IllegalStateException is thrown.
     * @return directory file
     * @throws IllegalStateException if file is not directory
     *
     */
    public File loadDir(String key, boolean mustExist, boolean mustBeReadable, boolean mustBeWritable) {
        File result = loadFile(key, mustExist, mustBeReadable, mustBeWritable);
        if (!result.isDirectory()) {
            throw new IllegalStateException("File " + result.getAbsolutePath() + " is not directory");
        }
        return result;
    }

    public boolean loadBoolean(String key) {
        String strValue = loadString(key);
        return Boolean.parseBoolean(strValue);
    }

    public int loadInt(String key) {
        String stringValue = loadString(key);
        try {
            return Integer.valueOf(stringValue);
        } catch (NumberFormatException e) {
            throw new NumberFormatException("Invalid value of property '" + key + "':" + e.getMessage());
        }
    }

    public Properties getProperties() {
        return properties;
    }
}
